package com.demo.base.redis.helper;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @author 曳戈泰尔
 * @version 1.0
 * @description Redis工具类 ZSet
 * @date 2023/4/26 9:53 PM
 */
@Slf4j
@Component
public class RedisSetHelper {

    /** Redis客户端 */
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    public void setStringRedisTemplate(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    /**
     * 向redis ZSet中设值
     *
     * @param key 键
     * @param value 值
     * @param score 分数
     * @return 是否设置成功
     */
    public boolean zSetAdd(String key, String value, double score) {
        boolean result = false;
        try {
            stringRedisTemplate.opsForZSet().add(key, value, score);
            result = true;
        } catch (Exception ex) {
            log.error("Redis设置ZSet缓存失败，原因：{}", ex.getMessage());
        }

        return result;
    }

    /**
     * 从redis ZSet中获取值 分页排序获取
     *
     * @param key 键
     * @param pageNum 页码
     * @param pageSize 页大小
     * @param isReverse 是否倒序
     * @return Map<String, Object> count 总数 set 值集合
     */
    public Map<String, Object> zSetRange(
            String key, long pageNum, long pageSize, boolean isReverse) {

        // 计算总数
        Long count = stringRedisTemplate.opsForZSet().zCard(key);
        if (count == null) {
            count = 0L;
        }

        // 计算分页
        long startIndex = (pageNum - 1) * pageSize;
        long endIndex = pageNum * pageSize - 1;

        // 值集合
        Set<String> set;

        // 是否倒叙
        if (!isReverse) {
            set = stringRedisTemplate.opsForZSet().range(key, startIndex, endIndex);
        } else {
            set = stringRedisTemplate.opsForZSet().reverseRange(key, startIndex, endIndex);
        }

        // 返回结果
        Map<String, Object> map = new HashMap<>();
        map.put("count", count);
        map.put("set", set);

        return map;
    }

    /**
     * 从redis ZSet中获取值 分页排序获取
     *
     * @param key 键
     * @param pageNum 页码
     * @param pageSize 页大小
     * @param isReverse 是否倒序
     * @return set 值集合
     */
    public Set<String> zSetRangeBackSet(
            String key, long pageNum, long pageSize, boolean isReverse) {

        // 计算分页
        long startIndex = (pageNum - 1) * pageSize;
        long endIndex = pageNum * pageSize - 1;

        // 值集合
        Set<String> set;

        // 是否倒叙
        if (!isReverse) {
            set = stringRedisTemplate.opsForZSet().range(key, startIndex, endIndex);
        } else {
            set = stringRedisTemplate.opsForZSet().reverseRange(key, startIndex, endIndex);
        }

        return set;
    }

    /**
     * 删除redis ZSet中的值
     *
     * <p>opsForZSet().add() 一般不使用 remove() 方法，直接 add 新值即可，会覆盖旧值
     *
     * @param key 键
     * @param value 值
     * @return 是否设置成功
     */
    public boolean zSetRemove(String key, String value) {
        boolean result = false;
        try {
            stringRedisTemplate.opsForZSet().remove(key, value);
            result = true;
        } catch (Exception ex) {
            log.error("Redis删除ZSet缓存失败，原因：{}", ex.getMessage());
        }

        return result;
    }

    /*
     * 批量删除redis ZSet中的值
     *
     * <p>使用stringRedisTemplate.delete()
     *
     * <p>对 opsForZSet().add() 生效
     */
}
